package cn.tedu.charging.order.mqtt;

import cn.tedu.charging.common.utils.JsonUtils;
import cn.tedu.charging.order.constant.Constants;
import cn.tedu.charging.order.constant.MqttConstant;
import cn.tedu.charging.order.constant.OrderStatusConstant;
import cn.tedu.charging.order.pojo.dto.ChargingResultDto;
import cn.tedu.charging.order.pojo.po.ChargingBillFailPO;
import cn.tedu.charging.order.pojo.po.ChargingBillSuccessPO;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;

/**
 * EMQX的消息中间的 消费者
 * 订单服务 用来 接收 设备发送的消息
 * 订单服务 用来 接收(订阅 subscribe) 设备发送的消息
 *
 * 1 订阅topic
 *  4个方法里,哪个放个来订阅topic 比较合理 连接成功 connectComplete 订阅topic
 *
 * 2 接收到消息
 *
 */
    @Slf4j
    public class MqttConsumer implements MqttCallbackExtended{
        private MqttClient mqttClient;
        private MqttContext mqttContext;
    /**
     * 通过写方法 setter设置
     */
  /*  public void setMqttClient(MqttClient mqttClient) {
        this.mqttClient = mqttClient;
    }*/

    /**
     * 通过构造器设置
     * 通过构造器设置 mqttClient
     *
     * 目前 还需要 mapper 一个成功的mapper,一个失败的mapper ,有可能后续还需要别的在容器里的对象
     * 1 修改构造器MqttConsumer 每次需要别的对象,都修改构造器
     *
     * 2
     */
        public  MqttConsumer(MqttContext mqttContext, MqttClient mqttClient){
            this.mqttClient=mqttClient;
            this.mqttContext=mqttContext;
        }

    @Override
    public void connectComplete(boolean reconnect, String serverURI) {
    log.debug("MqttConsumer#connectComplete方法被调用了,表示连接成功"+"reconnect:{},serverURI:{}",reconnect,serverURI);
        try {
    log.debug("连接成功,订阅开始充电指令的响应topic:{}", MqttConstant.TOPIC_CHARGING_RESULT);
            mqttClient.subscribe(MqttConstant.TOPIC_CHARGING_RESULT);
            log.debug("连接成功,订阅开始充电指令的响应topic:{},成功", MqttConstant.TOPIC_CHARGING_RESULT);
        } catch (MqttException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void connectionLost(Throwable cause) {
        log.debug("MqttConsumer#connectionLost方法被调用了,表示连接丢失"+cause);


    }

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        log.debug("MqttConsumer#messageArrived方法被调用了,表示消息到达"+"topic:{},message:{}",topic,message);
        ChargingResultDto chargingResultDto=null;
        try{
            //把设备发送的消息JSON转换为java对象 ChargingResultDto
             chargingResultDto = JsonUtils.fromJson(message.toString(),ChargingResultDto.class);
            log.debug("消息转换为对象:{}",chargingResultDto);
        }catch (Exception e) {
            log.error("设备发送的开始充电结果消息{}格式有问题,请检查!",message,e);
        }

            //判断设备返回的响应不能为空
            if (chargingResultDto != null) {
                //获取设备响应结果
                String result = chargingResultDto.getResult();
                //判断设备响应结果
                if (Constants.RESULT_START_CHARGING_SUCCESS.equals(result)) {
                    saveSuccessOrder(chargingResultDto);
                }else {
                    log.debug("通知充电用户,表示歉意,提醒用户更换充电枪");
                    log.debug("通知设备管理人员,进行设备检修");
                    saveFailOrder(chargingResultDto);
                }
            }

    }

    private void saveFailOrder(ChargingResultDto chargingResultDto) {
        log.debug("设备有响应,充电桩开始充电失败");
        ChargingBillFailPO chargingBillFailPO=new ChargingBillFailPO();
        chargingBillFailPO.setBillId(chargingResultDto.getOrderNo());
        chargingBillFailPO.setFailDesc("充电站故障-无法正常充电");
        log.debug("保存失败订单记录:{}",chargingBillFailPO);
        Integer row =mqttContext.getOrderFailMapper().insert(chargingBillFailPO);
        log.debug("保存失败订单记录:{},完成,影响行数:{}",chargingBillFailPO,row);
    }

    private void saveSuccessOrder(ChargingResultDto chargingResultDto) {
        log.debug("设备有响应,充电桩开始充电成功");
        ChargingBillSuccessPO po=new ChargingBillSuccessPO();
        po.setBillId(chargingResultDto.getOrderNo());
        //设置订单状态为充电中
        po.setBillStatus(OrderStatusConstant.ORDER_STATUS_PROGRESS);
        log.debug("保存成功订单记录:{}",po);
        Integer row =mqttContext.getOrderSuccessMapper().insert(po);
        log.debug("保存成功订单记录:{},成功,影响行数:{}",po,row);
    }


    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        log.debug("MqttConsumer#deliveryComplete方法被调用了,表示消息分发完成"+"token:{}",token);

    }
}
